package com.jushu.storbox.actions;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.jushu.storbox.R;
import com.jushu.storbox.ShareDriveApplication;
import com.jushu.storbox.callback.IDownloadThumbnailCallback;
import com.jushu.storbox.constant.Constant;
import com.jushu.storbox.constant.IntentConstant;
import com.jushu.storbox.constant.MessageCode;
import com.jushu.storbox.constant.UiConstant;
import com.jushu.storbox.database.DAOFactory;
import com.jushu.storbox.database.IFileDao;
import com.jushu.storbox.database.IFolderDao;
import com.jushu.storbox.entities.FileFolderInfo;
import com.jushu.storbox.entities.FileInfo;
import com.jushu.storbox.entities.FileType;
import com.jushu.storbox.entities.FolderInfo;
import com.jushu.storbox.handler.ClientExceptionRelateHandler;
import com.jushu.storbox.manager.DownloadTaskManager;
import com.jushu.storbox.service.ServiceFactory;
import com.jushu.storbox.task.tqueue.DownloadTask;
import com.jushu.storbox.task.tqueue.DownloadThumbnailTask;
import com.jushu.storbox.util.DirectoryUtil;
import com.jushu.storbox.util.PublicTools;
import com.jushu.storbox.view.dialog.ClouddriveDialog;
import com.huawei.sharedrive.sdk.android.exception.ClientException;
import com.huawei.sharedrive.sdk.android.model.request.FolderBaseRequest;
import com.huawei.sharedrive.sdk.android.modelV2.request.CopyFileRequestV2;
import com.huawei.sharedrive.sdk.android.modelV2.request.FolderCopyRequstV2;
import com.huawei.sharedrive.sdk.android.modelV2.request.FolderListRequestV2;
import com.huawei.sharedrive.sdk.android.modelV2.request.FolderMoveRequstV2;
import com.huawei.sharedrive.sdk.android.modelV2.request.LinkCreateRequestV2;
import com.huawei.sharedrive.sdk.android.modelV2.request.MoveFileRequestV2;
import com.huawei.sharedrive.sdk.android.modelV2.request.Order;
import com.huawei.sharedrive.sdk.android.modelV2.response.FileInfoResponseV2;
import com.huawei.sharedrive.sdk.android.modelV2.response.FolderListResponseV2;
import com.huawei.sharedrive.sdk.android.modelV2.response.FolderResponse;
import com.huawei.sharedrive.sdk.android.modelV3.response.LinkInfoV3;
import com.huawei.sharedrive.sdk.android.serviceV2.FileClientV2;
import com.huawei.sharedrive.sdk.android.serviceV2.FolderClientV2;
import com.huawei.sharedrive.sdk.android.serviceV2.NodeClient;
import com.huawei.sharedrive.sdk.android.util.StringUtil;

public class NodeAction extends BaseAction {
	
	public void downloadNodes(Context context, Handler msgHandler,
			final int msgCode, final List<FileFolderInfo> datas,
			final boolean isUpdateSync) {
		if (datas == null || datas.isEmpty()) {
			return;
		}
		executeRunTask(new RealTaskRunnable(context, msgHandler) {
			protected void doTask(Context context, Handler msgHandler)
					throws ClientException {
				List<FileFolderInfo> errorList = new ArrayList<FileFolderInfo>();
				int total = datas.size();
				int errorCount = 0;
				for (FileFolderInfo node : datas) {
					try {
						if (node.getType() == FileType.File.value()) {
							new DownloadEntity(context, msgHandler, node,
									isUpdateSync).startDownloadFile();
						} else if (node.getType() == FileType.Folder.value()) {
							new DownloadEntity(context, msgHandler, node,
									isUpdateSync).startDownloadFolder();
						}
					} catch (ClientException e) {
						errorList.add(node);
						errorCount++;
					}
				}

				Message msg = msgHandler.obtainMessage();
				msg.what = msgCode;
				msg.obj = errorList;
				msg.arg1 = total;
				msg.arg2 = errorCount;
				msg.sendToTarget();
			}

		});
	}

	public void deleteNodes(Context context, Handler msgHandler,
			final int messageCode, final List<FileFolderInfo> datas) {
		if (datas == null || datas.isEmpty()) {
			return;
		}
		executeRunTask(new RealTaskRunnable(context, msgHandler) {
			protected void doTask(Context context, Handler msgHandler)
					throws ClientException {
				for (FileFolderInfo node : datas) {
					Message msg = msgHandler.obtainMessage();
					try {
						if (node.getIsFile() == FileType.File.value()) {
							ServiceFactory.getRemoteFileService().deleteFile(
									node);
							ServiceFactory.instance(context)
									.getLocalFileService().deleteFile(node);
							DirectoryUtil.deleteFileThumbnailPath(context,
									node.getOwnerBy(), node.getId(),
									node.getName());
						} else if (node.getIsFile() == FileType.Folder.value()) {
							ServiceFactory.getRemoteFolderService()
									.deleteFolder(node);
						}
						msg.what = messageCode;
						msg.obj = node;
					} catch (ClientException e) {
						msg.what = e.getStatusCode();
						msg.obj = e;
					}
					msg.sendToTarget();
				}
			}
		});
	}

	public void saveToTeamSpace(Context context, Handler msgHandler,
			final int messageCode, final List<FileFolderInfo> datas,
			final String targetFolderId, final String targetOwnerId) {
		if (datas == null || datas.isEmpty()) {
			return;
		}
		if (StringUtil.isBlank(targetFolderId)
				|| StringUtil.isBlank(targetOwnerId)) {
			return;
		}
		executeRunTask(new RealTaskRunnable(context, msgHandler) {
			ArrayList<FileFolderInfo> errorData = new ArrayList<FileFolderInfo>();
			protected void doTask(Context context, Handler msgHandler)
					throws ClientException {
				for (FileFolderInfo node : datas) {
					try {
						if (node.getIsFile() == FileType.File.value()) {
							// init request data
							CopyFileRequestV2 request = new CopyFileRequestV2();
							request.setAutoRename(false);
							request.setDestOwnerId(Long.valueOf(targetOwnerId));
							request.setDestParent(Long.valueOf(targetFolderId));
							request.setLink(null);
							// request server do task
							ServiceFactory.getRemoteFileService().copyFile(
									node.getOwnerId(), node.getId(), request);
						} else if (node.getIsFile() == FileType.Folder.value()) {
							// init request data
							FolderCopyRequstV2 request = new FolderCopyRequstV2();
							request.setAutoRename(false);
							request.setDestParent(targetFolderId);
							request.setDestOwnerId(targetOwnerId);
							// request server do task
							ServiceFactory.getRemoteFolderService().copyFolder(
									node.getOwnerId(), node.getId(), request);
						}
					} catch (ClientException e) {
						if(e.getStatusCode() == ClientExceptionRelateHandler.ERROR_CODE_409_SOURCE_CONFLICT
								&& ClientExceptionRelateHandler.RepeatNameConflict.equals(e.getCode())) {
							errorData.add(node);
						} else {
							Message msg = msgHandler.obtainMessage();
							msg.what = e.getStatusCode();
							msg.obj = e;
							msg.sendToTarget();
						}
							
					}
				}
				if(errorData != null && errorData.isEmpty()){
					Message msg = msgHandler.obtainMessage();
					msg.what = UiConstant.NODES_ACTION_COPY_ALL_SUCCESS;
					msg.sendToTarget();
				} else {
					ClientException e = new ClientException(ClientExceptionRelateHandler.ERROR_CODE_409_SOURCE_CONFLICT,
							ClientExceptionRelateHandler.RepeatNameConflict, "conflict!");
					throw e;
				}
			}
			
			@Override
			protected boolean filterException(ClientException e, final Handler handler) {
				if(e.getStatusCode() == ClientExceptionRelateHandler.ERROR_CODE_409_SOURCE_CONFLICT
						&& ClientExceptionRelateHandler.RepeatNameConflict.equals(e.getCode())) {
		            handler.post(new Runnable(){
						@Override
						public void run() {
							final ClouddriveDialog move = new ClouddriveDialog(context, R.style.dialog_upload,
					                R.layout.dialog_filedelete);
				            View conventView = move.getConventView();
				            Button dialog_cancal = (Button) conventView.findViewById(R.id.dialog_add_file_cancal_bt);
				            Button dialog_OK = (Button) conventView.findViewById(R.id.dialog_add_file_ok_bt);
				            TextView dialog_prompt_tv = (TextView) conventView.findViewById(R.id.dialog_prompt_tv);
				            dialog_prompt_tv.setText(context.getString(R.string.allfile_confirm_reanme_filefolder));
				            dialog_cancal.setOnClickListener(new View.OnClickListener() {
				                @Override
				                public void onClick(View v) {
				                	move.dismiss(); //批量转存到团队空间（取消）
				                	handler.sendEmptyMessage(UiConstant.NODES_ACTION_COPY_TEMA_CANCEL);
				                }
				            });
				            dialog_OK.setOnClickListener(new View.OnClickListener() {
				                @Override
				                public void onClick(View v) {
				                	move.dismiss();
				                	copyWithAutoRename(context, UiConstant.NODES_ACTION_COPY_ALL_SUCCESS, errorData,
				                			targetFolderId, targetOwnerId, msgHandler);
				                }
				            });
				            move.show();
						}
		            });
					return true;
				} else {
					return false;
				}
			}
		});
	}
	
	private void copyWithAutoRename(Context context, final int messageCode, 
			final ArrayList<FileFolderInfo> datas_for_rename, final String targetFolderId, 
			final String targetOwnerId, Handler msgHandler) {
		executeRunTask(new RealTaskRunnable(context, msgHandler) {
			ArrayList<FileFolderInfo> tempList = new ArrayList<FileFolderInfo>();
			
			protected void doTask(Context context, Handler msgHandler)
					throws ClientException {
				for(FileFolderInfo node : datas_for_rename){
					Message msg = msgHandler.obtainMessage();
					try {
						if (node.getIsFile() == FileType.File.value()) {
							// init request data
							CopyFileRequestV2 request = new CopyFileRequestV2();
							request.setAutoRename(true);
							request.setDestOwnerId(Long.valueOf(targetOwnerId));
							request.setDestParent(Long.valueOf(targetFolderId));
							request.setLink(null);
							// request server do task
							ServiceFactory.getRemoteFileService().copyFile(
									node.getOwnerId(), node.getId(), request);
						} else if (node.getIsFile() == FileType.Folder.value()) {
							// init request data
							FolderCopyRequstV2 request = new FolderCopyRequstV2();
							request.setDestParent(targetFolderId);
							request.setDestOwnerId(targetOwnerId);
							// request server do task
							ServiceFactory.getRemoteFolderService().copyFolder(
									node.getOwnerId(), node.getId(), request);
						}
						tempList.add(node);
					} catch (ClientException e) {
						msg.what = e.getStatusCode();
						msg.obj = e;
					}
					msg.sendToTarget();
				}
				
				if(tempList.size() == datas_for_rename.size()) {
					Message msg = msgHandler.obtainMessage();
					msg.what = UiConstant.NODES_ACTION_COPY_ALL_SUCCESS;
					msg.sendToTarget();
				} else {
					Message msg = msgHandler.obtainMessage();
					msg.what = UiConstant.NODES_ACTION_COPY_SOME_SUCCESS;
					msg.sendToTarget();
				}
			}
			
			
		});
	}

	public void moveNodes(Context context, Handler msgHandler,
			final int messageCode, final List<FileFolderInfo> datas,
			final String targetFolderId, final String targetOwnerId) {
		if (datas == null || datas.isEmpty()) {
			return;
		}
		if (StringUtil.isBlank(targetFolderId)
				|| StringUtil.isBlank(targetOwnerId)) {
			return;
		}
		
		executeRunTask(new RealTaskRunnable(context, msgHandler) {
			private ArrayList<FileFolderInfo> datasMoveFailure = new ArrayList<FileFolderInfo>();
			private String errorCode = null;
			protected void doTask(Context context, Handler msgHandler)
					throws ClientException {
				for (FileFolderInfo node : datas) {
					try {
						if (node.getType() == FileType.File.value()) {
							MoveFileRequestV2 request = new MoveFileRequestV2();
							request.setDestParent(Long.valueOf(targetFolderId));
							request.setAutoRename(false);
							request.setDestOwnerId(Long.valueOf(targetOwnerId));
							FileClientV2.getInstance().moveFile(
									node.getOwnerId(), node.getId(), request,
									getAuthCode());
						} else if (node.getType() == FileType.Folder.value()) {
							FolderMoveRequstV2 request = new FolderMoveRequstV2();
							request.setDestParent(targetFolderId);
							request.setAutoRename(false);
							request.setDestOwnerId(targetOwnerId);
							FolderClientV2.getInstance().moveFolder(
									node.getOwnerId(), node.getId(),
									getAuthCode(), request);
						}
						Message msg = msgHandler.obtainMessage();
						msg.what = UiConstant.NODES_ACTION_MOVE_ITEM_SUCCESS;
						msg.obj = node;
						msg.sendToTarget();
					} catch (ClientException e) {
						if(e.getStatusCode() == ClientExceptionRelateHandler.ERROR_CODE_409_SOURCE_CONFLICT
								&& ClientExceptionRelateHandler.SameParentConflict.equals(e.getCode())){
							errorCode = ClientExceptionRelateHandler.SameParentConflict;
							break;
						}else if(e.getStatusCode() == ClientExceptionRelateHandler.ERROR_CODE_409_SOURCE_CONFLICT
								&& ClientExceptionRelateHandler.RepeatNameConflict.equals(e.getCode())){
							datasMoveFailure.add(node);
							errorCode = ClientExceptionRelateHandler.RepeatNameConflict;
						}else{
							Message msg = msgHandler.obtainMessage();
							msg.what = e.getStatusCode();
							msg.obj = e;
							msg.sendToTarget();
						}
					}
				}
				if(errorCode == null){
					if(datasMoveFailure != null && datasMoveFailure.isEmpty()){
						Message msg = msgHandler.obtainMessage();
						msg.what = UiConstant.NODES_ACTION_MOVE_ALL_SUCCESS;
						msg.sendToTarget();
					}
				}
				/*原地移动*/
				if(errorCode !=null && errorCode.equals(ClientExceptionRelateHandler.SameParentConflict)){
					Message msg = msgHandler.obtainMessage();
					msg.what = UiConstant.NODES_ACTION_MOVE_TAGET_SAME_PARENT;
					msg.sendToTarget();
				}
				/*文件重名*/
				if(errorCode !=null && errorCode.equals(ClientExceptionRelateHandler.RepeatNameConflict)){
					if(datasMoveFailure != null && !datasMoveFailure.isEmpty()){
						ClientException e = new ClientException(ClientExceptionRelateHandler.ERROR_CODE_409_SOURCE_CONFLICT,
								ClientExceptionRelateHandler.RepeatNameConflict, "conflict!");
						throw e;
					}
				}
			}
			@Override
			protected boolean filterException(ClientException e, final Handler handler) {
				if(e.getStatusCode() == ClientExceptionRelateHandler.ERROR_CODE_409_SOURCE_CONFLICT
						&& ClientExceptionRelateHandler.RepeatNameConflict.equals(e.getCode())) {
					msgHandler.post(new Runnable(){
						@Override
						public void run() {
							final ClouddriveDialog move = new ClouddriveDialog(context, R.style.dialog_upload,
					                R.layout.dialog_filedelete);
				            View conventView = move.getConventView();
				            Button dialog_cancal = (Button) conventView.findViewById(R.id.dialog_add_file_cancal_bt);
				            Button dialog_OK = (Button) conventView.findViewById(R.id.dialog_add_file_ok_bt);
				            TextView dialog_prompt_tv = (TextView) conventView.findViewById(R.id.dialog_prompt_tv);
				            dialog_prompt_tv.setText(context.getString(R.string.allfile_confirm_reanme_filefolder));
				            dialog_cancal.setOnClickListener(new View.OnClickListener() {
				                @Override
				                public void onClick(View v) {
				                	move.dismiss();
				                	handler.obtainMessage(UiConstant.NODES_ACTION_MOVE_CANCAL,null).sendToTarget();
				                }
				            });
				            dialog_OK.setOnClickListener(new View.OnClickListener() {
				                @Override
				                public void onClick(View v) {
				                	move.dismiss();
				                	moveNodeWithAutoRename(context, messageCode, datasMoveFailure,
				                			targetFolderId, targetOwnerId, msgHandler);
				                }
				            });
				            move.show();
						}
					});
					return true;
				}
				return super.filterException(e, handler);
			}
		});
	}

	private void moveNodeWithAutoRename(Context context, final int messageCode, 
			final ArrayList<FileFolderInfo> datas_for_rename, final String targetFolderId, 
			final String targetOwnerId, Handler msgHandler) {
		executeRunTask(new RealTaskRunnable(context, msgHandler) {
			ArrayList<FileFolderInfo> tempList = new ArrayList<FileFolderInfo>();
			
			protected void doTask(Context context, Handler msgHandler)
					throws ClientException {
				for(FileFolderInfo node : datas_for_rename){
					Message msg = msgHandler.obtainMessage();
					try {
						if (node.getType() == FileType.File.value()) {
							MoveFileRequestV2 request = new MoveFileRequestV2();
							request.setDestParent(Long.valueOf(targetFolderId));
							request.setAutoRename(true);
							request.setDestOwnerId(Long.valueOf(targetOwnerId));
							FileClientV2.getInstance().moveFile(
									node.getOwnerId(), node.getId(), request,
									getAuthCode());
						} else if (node.getType() == FileType.Folder.value()) {
							FolderMoveRequstV2 request = new FolderMoveRequstV2();
							request.setDestParent(targetFolderId);
							request.setAutoRename(true);
							request.setDestOwnerId(targetOwnerId);
							FolderClientV2.getInstance().moveFolder(
									node.getOwnerId(), node.getId(),
									getAuthCode(), request);
						}
						msg.what = UiConstant.NODES_ACTION_MOVE_ITEM_SUCCESS;
						msg.obj = node;
						tempList.add(node);
					} catch (ClientException e) {
						msg.what = e.getStatusCode();
						msg.obj = e;
					}
					msg.sendToTarget();
				
				}
				
				if(tempList.size() == datas_for_rename.size()) {
					Message msg = msgHandler.obtainMessage();
					msg.what = UiConstant.NODES_ACTION_MOVE_ALL_SUCCESS;
					msg.sendToTarget();
				} else {
					Message msg = msgHandler.obtainMessage();
					msg.what = UiConstant.NODES_ACTION_MOVE_SOME_SUCCESS;
					msg.sendToTarget();
				}
			}
		});
	}
	
	public void createLink(final Context context,
			final FileFolderInfo fileInformation, final Handler messageHandler) {
		executeRunTask(new RealTaskRunnable(context, messageHandler) {
			protected void doTask(Context context, Handler msgHandler)
					throws ClientException {

				LinkInfoV3 linkInfo = ServiceFactory.getRemoteFolderService()
						.createLink(fileInformation);
				if (fileInformation.getIsFile() == 1) {
					DAOFactory.instance(context).getFileDao()
							.setShareLink(fileInformation, true);
				} else {
					DAOFactory.instance(context).getFolderDao()
							.setFolderLink(fileInformation, true);
				}

				Bundle fileInfoBundle = new Bundle();
				fileInfoBundle.putSerializable("FileFolderInfo",
						fileInformation);
				fileInfoBundle.putSerializable("LinkInfo", linkInfo);
				fileInfoBundle.putSerializable("LinkConfigInfo", Boolean
						.valueOf(ServiceFactory.getRemoteFolderService()
								.isComplexLinkCode(
										ShareDriveApplication.getInstance()
												.getAuthorization())));
				Message msg = messageHandler.obtainMessage();
				msg.what = MessageCode.LINK_CREATE;
				msg.setData(fileInfoBundle);
				msg.sendToTarget();
			}
		});
	}

	public void updateLink(final Context context,
			final FileFolderInfo fileInformation,
			final LinkCreateRequestV2 request, final Handler messageHandler) {
		executeRunTask(new RealTaskRunnable(context, messageHandler) {
			protected void doTask(Context context, Handler msgHandler)
					throws ClientException {
				LinkInfoV3 linkInfo = ServiceFactory.getRemoteFolderService()
						.updateLink(fileInformation, request);
				Bundle fileInfoBundle = new Bundle();
				fileInfoBundle.putSerializable("FileFolderInfo",
						fileInformation);
				fileInfoBundle.putSerializable("LinkInfo", linkInfo);
				Message msg = messageHandler.obtainMessage();
				msg.what = MessageCode.LINK_UPDATE;
				msg.setData(fileInfoBundle);
				msg.sendToTarget();
			}
		});
	}

	public void getLinkList(final Context context,
			final FileFolderInfo fileInformation, final Handler messageHandler) {
		executeRunTask(new RealTaskRunnable(context, messageHandler) {
			protected void doTask(Context context, Handler msgHandler)
					throws ClientException {
				List<LinkInfoV3> linkInfo = ServiceFactory
						.getRemoteFolderService().getLink(fileInformation);
				Message msg = messageHandler.obtainMessage();
				msg.what = MessageCode.LINK_LIST;
				msg.obj = linkInfo;
				msg.sendToTarget();
			}
		});
	}

	public void getLinkConfig(final Context context,final FileFolderInfo fileInformation, final LinkInfoV3 linkInfo, final Handler messageHandler) {
		executeRunTask(new RealTaskRunnable(context, messageHandler) {
			protected void doTask(Context context, Handler msgHandler)
					throws ClientException {
				boolean linkConfig = ServiceFactory.getRemoteFolderService()
						.isComplexLinkCode(
								ShareDriveApplication.getInstance()
										.getAuthorization());
				Bundle fileInfoBundle = new Bundle();
				fileInfoBundle.putSerializable("FileFolderInfo",
						fileInformation);
				fileInfoBundle.putSerializable("LinkInfo", linkInfo);
				fileInfoBundle.putSerializable("LinkConfigInfo", linkConfig);
				Message msg = messageHandler.obtainMessage();
				msg.what = MessageCode.LINK_CONFIG;
				msg.setData(fileInfoBundle);
				msg.sendToTarget();
			}
		});
	}

	public void deleteLink(final Context context,
			final FileFolderInfo fileInformation, final LinkInfoV3 linkInfo,
			final Handler messageHandler) {
		executeRunTask(new RealTaskRunnable(context, messageHandler) {
			protected void doTask(Context context, Handler msgHandler)
					throws ClientException {
				ServiceFactory.getRemoteFolderService().deleteLink(
						fileInformation, linkInfo.getId());
				if (fileInformation.getIsFile() == 1) {
					DAOFactory.instance(context).getFileDao()
							.setShareLink(fileInformation, false);
				} else {
					DAOFactory.instance(context).getFolderDao()
							.setFolderLink(fileInformation, false);
				}
				Message msg = messageHandler.obtainMessage();
				msg.what = MessageCode.LINK_DELETE;
				msg.obj = linkInfo;
				msg.sendToTarget();
			}
		});
	}

	public void cleanNodeCatch(Context context, Handler messageHandler,
			final FileFolderInfo info) {
		executeRunTask(new RealTaskRunnable(context, messageHandler) {
			@Override
			protected void doTask(Context context, Handler msgHandler)
					throws ClientException {
				
				info.setSync(false);
				info.notifyChange();
				
				Set<DownloadTask> tasks = DownloadTaskManager.getAllTaskes();
				if (tasks != null && tasks.size() > 0) {
					for (DownloadTask task : tasks) {
						if(info.getId().equals(task.getId()) && info.getOwnerId().equals(task.getOwnerID())){
							task.cancelDownloadTask();
							DownloadTaskManager.getAllFailTasks().remove(task);
//							break;
						}
					}
				}
				
				if(info.getIsFile() == FileType.File.value()) {
					IFileDao fileDao = DAOFactory.instance(context).getFileDao();
					cleanFileCatch(info, fileDao);
					info.setSync(false);
					info.setTransStatus(Constant.DOWNLOAD_NON_UPDATE_DB);
					info.notifyChange();
				} else if(info.getIsFile() == FileType.Folder.value()) {
					IFolderDao folderDao = DAOFactory.instance(context).getFolderDao();
					IFileDao fileDao = DAOFactory.instance(context).getFileDao();
					cleanFolderCatch(info, folderDao, fileDao);
					info.setSync(false);
					info.setTransStatus(Constant.DOWNLOAD_NON_UPDATE_DB);
					info.notifyChange();
				}
			}
			
			private void cleanFileCatch(FileFolderInfo fileInfo, IFileDao fileDao) {
				String filePath = DirectoryUtil.generateFileDownloadPath(context, fileInfo.getOwnerBy(), 
						fileInfo.getId(), fileInfo.getName());
				File localPath = new File(filePath);
				if(localPath.exists()) {
					localPath.delete();
				}
				fileDao.updateSyncStatus(fileInfo, Constant.DOWNLOAD_STATUS_NOCACHE_DB);
				fileDao.updateTransStatus(fileInfo, Constant.DOWNLOAD_NON_UPDATE_DB);
			}
			
			private void cleanFolderCatch(FileFolderInfo info, IFolderDao folderDao, IFileDao fileDao) {
				folderDao.updateSyncStatuc(info.getOwnerBy(), info.getId(), Constant.DOWNLOAD_STATUS_NOCACHE_DB);
				folderDao.updateTransStatus(info.getOwnerBy(), info.getId(), Constant.DOWNLOAD_NON_UPDATE_DB);
				
				List<FileInfo> fileList = fileDao.getFileList(info);
				for(FileInfo tempFileInfo : fileList) {
					cleanFileCatch(tempFileInfo, fileDao);
				}
				
				List<FolderInfo> folderList = folderDao.getFolderList(info.getOwnerBy(), info.getId());
				for(FolderInfo tempFolderInfo : folderList) {
					cleanFolderCatch(tempFolderInfo, folderDao, fileDao);
				}
			}
		});
	}

	public void syncNode(Context context, Handler messageHandler, final FileFolderInfo mInfo) {
		executeRunTask(new RealTaskRunnable(context, messageHandler) {
			@Override
			protected void doTask(Context context, Handler msgHandler)
					throws ClientException {
				if(mInfo.getIsFile() == FileType.File.value()) {
					syncFile(mInfo);
				} else if(mInfo.getIsFile() == FileType.Folder.value()) {
					syncFolder(mInfo);
				}
			}

			private void syncFolder(FileFolderInfo info) throws ClientException {
				IFolderDao folderDao = DAOFactory.instance(context).getFolderDao();
				IFileDao fileDao = DAOFactory.instance(context).getFileDao();
				//get folder self's information from server
				FolderBaseRequest folderRequest = new FolderBaseRequest();
				folderRequest.setFolderID(info.getId());
				folderRequest.setOwnerID(info.getOwnerBy());
				folderRequest.setAuthorization(getAuthCode());
				FolderResponse folder = FolderClientV2.getInstance().getFolderInfo(folderRequest);

				doSyncFolder(folder, folderDao, fileDao);

				new Thread(new VirtureProgress(context, info)).start();

				//notify ui conpent
				info.notifyChange();
			}
			
			private void doSyncFolder(FolderResponse folder, IFolderDao folderDao, IFileDao fileDao) throws ClientException {
				//update folder information 
				FolderInfo localFolder = folderDao.getFolderById(folder.getOwnedBy(), folder.getId());
				if(localFolder == null) {
					localFolder = new FolderInfo();
					localFolder.valueOf(folder);
					localFolder.setSync(true);
					localFolder.setContentSyncState(Constant.SYNC_STATUS_TRUE);
					localFolder.setTransStatus(Constant.DOWNLOAD_SUCCESS_UPDATE_DB);
					folderDao.insertFolder(localFolder);
				} else if(folder.getModifiedAt() != localFolder.getModifiedAt()) {
					localFolder.copyFiledValue(folder);
					localFolder.setSync(true);
					localFolder.setContentSyncState(Constant.SYNC_STATUS_TRUE);
					localFolder.setTransStatus(Constant.DOWNLOAD_SUCCESS_UPDATE_DB);
					folderDao.updateFolder(localFolder);
				}
				
				List<Order> olist = new ArrayList<Order>();
//				olist.add(new Order(Order.ORDER_FILED_TYPE, Order.ORDER_TYPE_ASC));
				olist.add(new Order(Order.ORDER_FILED_MODIFY_AT, Order.ORDER_TYPE_DESC));
				
				//get folder's sub collections
				FolderListRequestV2 request = new FolderListRequestV2();
				request.setFolderID(folder.getId());
				request.setLimit(1000);
				request.setOffset(0);
				request.setOwnerID(folder.getOwnedBy());
				request.setOrder(olist);
				FolderListResponseV2 response = FolderClientV2.getInstance().getFolderInfoList(request , getAuthCode());

				//process subfiles
				List<FileInfoResponseV2> files = response.getFiles();

				for(FileInfoResponseV2 tempFile : files) {
					FileInfo localFile = fileDao.getFile(tempFile.getOwnedBy(), tempFile.getId());
					Log.i("test", "localFile = " + localFile);
					if(localFile == null) {
						localFile = new FileInfo();
						localFile.valueOf(tempFile);
						localFile.setSync(true);
						fileDao.insertFile(localFile);
						DownloadTaskManager.addTask(new DownloadTask(context, null, localFile, true));
					} else if(tempFile.getModifiedAt() != localFile.getModifiedAt()) {
						localFile.copyFiledValue(tempFile);
						localFile.setSync(true);
						fileDao.update(localFile);
						if(!tempFile.getIdentity().equals(localFile.getIdentity())) {
							DownloadTaskManager.addTask(new DownloadTask(context, null, localFile, true));
						}
					} else {
						String filePath = DirectoryUtil.generateFileDownloadPath(context, localFile);
						File file = new File(filePath);
						if(!file.exists()) {
							DownloadTaskManager.addTask(new DownloadTask(context, null, localFile, true));
						} else if(localFile.getContentSyncState() == Constant.SYNC_STATUS_FALSE
								|| !tempFile.getIdentity().equals(localFile.getLocalIdentity())) {
							file.delete();
							DownloadTaskManager.addTask(new DownloadTask(context, null, localFile, true));
						}
					}
				}
				//process sub folders
				List<FolderResponse> folders = response.getFolders();
				for(FolderResponse tempFolder : folders) {
					doSyncFolder(tempFolder, folderDao, fileDao);
				}
			}

			private void syncFile(final FileFolderInfo mInfo) {
				String serverIdentity = mInfo.getIdentity();
				if(!StringUtil.isBlank(serverIdentity)
						&& !serverIdentity.equals(mInfo.getLocalIdentity())) {
					String filePath = DirectoryUtil.generateFileDownloadPath(context, mInfo);
					File realFile = new File(filePath);
					if(realFile.exists()) {
						realFile.delete();
					}
					if(PublicTools.isFileType(realFile.getName(), Constant.IMAGE_TYPE)) {
						String thumbnalPath = DirectoryUtil.genThumbnailFileFullName(context, mInfo);
						File thumbFile = new File(thumbnalPath);
						if(thumbFile.exists()) {
							thumbFile.delete();
							
							DownloadThumbnailTask task = new DownloadThumbnailTask(
					        		ShareDriveApplication.getInstance().getAuthorization(), 
					        		mInfo.getOwnerBy(), mInfo.getId(), thumbnalPath,
					        		new IDownloadThumbnailCallback() {
					        			public void onStart() { }
					        			public void onFailure(Throwable t) {
					        				DownloadTaskManager.addTask(new DownloadTask(context, null, mInfo, true));
					        			}
					        			public void onProgress(int currentProgress,long currentSize, long maxSize) { }
					        			public void onSuccess(String fileId) {
					        				DownloadTaskManager.addTask(new DownloadTask(context, null, mInfo, true));
					        			}
					        		});
							
							executeRunTask(task);
						}
					} else {
						DownloadTaskManager.addTask(new DownloadTask(context, null, mInfo, true));
					}
				}
			}
		});
	}

	public void getNodePath(Context context, final Handler messageHandler,  final FileFolderInfo fileInformation){
		executeRunTask(new RealTaskRunnable(context, messageHandler) {
			protected void doTask(Context context, Handler msgHandler) throws ClientException {
				List<FolderResponse> values = new NodeClient().getNodePath(ShareDriveApplication.getInstance().getAuthorization(), 
						fileInformation.getOwnerBy(), fileInformation.getId());
				Message msg = messageHandler.obtainMessage();
				msg.what = UiConstant.NODE_ACTION_GET_PATH;
				msg.obj = values;
				Bundle bundle = new Bundle();
				bundle.putSerializable(IntentConstant.INTENT_DATA_EXTENDS_1,fileInformation);
				msg.setData(bundle);
				msg.sendToTarget();
			}
		});
	}

}
